package code

import (
	"fmt"
	"net/http"
)

// CorrectionFactorCoder 修正因子的coder，推荐使用NexXXX方法创建
type CorrectionFactorCoder struct {
	// ErrorCode 错误代码
	errorCode int
	// CorrectionFactor 修正因子：为了适配有些的方的编码重复和不规范，设计这个数值，最终返回给前端的错误码是 ErrorCode和 CorrectionFactor的和
	correctionFactor int
	// HttpStatus http的状态码
	httpStatus int
	// Message 错误信息，也可以是format字符串，最终的结果是Message和传入的参数format的结果
	message string
	// 消息的中文
	messageCh string

	//所有的消息，这是为了适配不仅有中文和英文的情况，如果该消息有值，0的位置为中文，1的位置为英文，
	messages []string
	// Reference 返回用户的详细文档
	reference string
}

// New 全部参数的创建函数
func New(errorCode, httpStatus, correctionFactor int, message, messageCh, reference string, messages []string) Coder {
	code := &CorrectionFactorCoder{
		errorCode:        errorCode,
		correctionFactor: correctionFactor,
		httpStatus:       httpStatus,
		message:          message,
		messageCh:        messageCh,
		reference:        reference,
		messages:         messages,
	}
	if messageCh == "" && len(messages) >= 1 {
		messageCh = messages[0]
	}
	if message == "" && len(messages) >= 2 {
		message = messages[1]
	}
	if len(messages) == 0 {
		messages = append(messages, messageCh)
		messages = append(messages, message)
	}
	return code
}

func NewWithoutRef(errorCode, httpStatus, correctionFactor int, message string, messageCh string) Coder {
	return New(errorCode, httpStatus, correctionFactor, message, messageCh, "", make([]string, 0))
}

func NewWithMessages(errorCode, correctionFactor int, messages []string) Coder {
	return New(errorCode, http.StatusInternalServerError, correctionFactor, "", "", "", messages)
}

func NewWithoutFactorAndRef(errorCode, httpStatus int, message, messageCh string) Coder {
	return New(errorCode, httpStatus, 0, message, messageCh, "", make([]string, 0))
}

func NewWithInternalError(errorCode, correctionFactor int, message string, messageCh string) Coder {
	return New(errorCode, http.StatusInternalServerError, correctionFactor, message, messageCh, "", make([]string, 0))
}

func NewWithCodeAndMessage(errorCode int, message string, messageCh string) Coder {
	return New(errorCode, http.StatusInternalServerError, 0, message, messageCh, "", make([]string, 0))
}

func (c *CorrectionFactorCoder) ErrorCode() int {
	return c.errorCode
}

func (c *CorrectionFactorCoder) Code() int {
	return c.errorCode + c.correctionFactor
}

func (c *CorrectionFactorCoder) HttpStatus() int {
	return c.httpStatus
}

func (c *CorrectionFactorCoder) Message() string {
	return c.message
}

func (c *CorrectionFactorCoder) MessageCh() string {
	return c.messageCh
}

func (c *CorrectionFactorCoder) Messages() []string {
	return c.messages
}

func (c *CorrectionFactorCoder) MessagesF(values ...any) []string {
	if len(c.messages) == 0 {
		return []string{}
	}
	messagesF := make([]string, 0)
	for _, message := range c.messages {
		messagesF = append(messagesF, fmt.Sprintf(message, values...))
	}
	return messagesF
}

func (c *CorrectionFactorCoder) MessageF(values ...any) string {
	return fmt.Sprintf(c.message, values...)
}

func (c *CorrectionFactorCoder) MessageChF(values ...any) string {
	return fmt.Sprintf(c.messageCh, values...)
}

func (c *CorrectionFactorCoder) Reference() string {
	return c.reference
}
